package com.topisv.tms.service.work;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
//import com.topisv.tms.api.TaoBaoAPITool;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.interfacetask.InterfaceTask;
import com.topisv.tms.entity.interfacetask.InterfaceTaskEnum;
import com.topisv.tms.entity.log.OrderLog;
import com.topisv.tms.entity.work.WholePileConfig;
import com.topisv.tms.entity.work.WorkBatch;
import com.topisv.tms.entity.work.WorkLog;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.WorkTask;
import com.topisv.tms.entity.work.WorkTaskItem;
import com.topisv.tms.repository.AreaGroupDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.log.OrderLogDao;
import com.topisv.tms.repository.work.WholePileConfigDao;
import com.topisv.tms.repository.work.WorkBatchDao;
import com.topisv.tms.repository.work.WorkLogDao;
import com.topisv.tms.repository.work.WorkOrderDao;
import com.topisv.tms.repository.work.WorkTaskDao;
import com.topisv.tms.repository.work.WorkTaskItemDao;
import com.topisv.tms.rest.entity.Batch;
import com.topisv.tms.rest.entity.Box;
import com.topisv.tms.rest.entity.Box_detail;
import com.topisv.tms.rest.entity.Order;
import com.topisv.tms.rest.qimen.qmsend.QmRequestSender;
import com.topisv.tms.rest.qimen.qmservice.DeliveryProcessService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.base.BaseService;
import com.topisv.tms.service.interfacetask.InterfaceTaskService;
import com.topisv.tms.tools.TransferHelper;
import com.topisv.tms.utils.TimeUtil;
//import com.topisv.tms.utils.http.SynchroShippedBatchQueue;

/**
 * 作业批次_service
 * @author ch
 */
@Component
@Transactional(readOnly = true)
public class WorkBatchService extends BaseService{

	private static final Logger logger = LoggerFactory.getLogger(WorkBatchService.class);

	@Autowired
	private WorkBatchDao workBatchDao;
	@Autowired
	private WorkTaskDao workTaskDao;
	@Autowired
	private WorkTaskItemDao workTaskItemDao;
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private WorkLogDao workLogDao;
	@Autowired
	private OrderLogDao orderLogDao;
	@Autowired
	private WorkOrderDao workOrderDao;
	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private AreaGroupDao areaGroupDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Resource(type=DeliveryProcessService.class)
	QmRequestSender<Map<String,Object>> deliveryProcessService;
	@Autowired
	private WholePileConfigDao wpcDao;
	@Autowired
    private InterfaceTaskService interfaceTaskService;
	/**
	 * 创建作业批次
	 * @param orderNum 单个批次的订单数量限制
	 * @param customerCode  商家代码
	 * @param warehouseCode 作业仓库
	 * @param ordersArray 订单数组
	 * @param pickType 订单类型 （single:单件  multi:多件）
	 * @throws Exception
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void createWorkBatch(String tacticsType, Integer orderNum, String customerCode, String companyCode,
			String warehouseCode, String[] ordersArray, String pickType, String billType, String flowType, String psFlag) throws Exception {
		try {
			ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			User curUser=this.userDao.findOne(user.id);
			
			List<WorkBatch> batchList=new ArrayList<WorkBatch>();
			List<EdiOrder> orderList=new ArrayList<EdiOrder>();
			List<WorkLog> workLogList=new ArrayList<WorkLog>();
			List<OrderLog> orderLogList=new ArrayList<OrderLog>();
			List<WorkOrder> workOrderList=new ArrayList<WorkOrder>();
			DecimalFormat df=new DecimalFormat("0000000");
			
			WorkBatch workBatch=null;
			WorkLog workLog;
			Date now=null;
			
			String sku_last="";
			
			if("wholePile".equals(tacticsType) ){
				//获取整托配置
				List<WholePileConfig> wpcList = wpcDao.findAll();
				Map<String ,WholePileConfig> wpcMap = new HashMap<String,WholePileConfig>();
				for(WholePileConfig wpc:wpcList){
					String key = wpc.getCustomerCode()+":"+wpc.getWarehouseCode()+":"+wpc.getSku();
					wpcMap.put(key,wpc);
				}
				
				//workBatchCode对应的整托配置数量
				Map<String,WholePileConfig> wbRelwpMap = new HashMap<String,WholePileConfig>();
				//warehouseCode+customerCode+sku对应的workBatch  如果该组合的订单数量已经满足了整托数量则会新生成一个批次代替。
				Map<String,WorkBatch> wholePileMap = new HashMap<String,WorkBatch>();
				
				
				
				Map<String,List<String>> skuOrderMap = new HashMap<String,List<String>>();
					
				for (int i = 0; i < ordersArray.length; i++) {
					//整托拣选
					String orderno = ordersArray[i];
					List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(orderno);
					String sku=itemList.get(0).getSku();
					String cusCode = itemList.get(0).getCustomerCode();
					//获取整托配置
					String key = cusCode +":"+warehouseCode+":"+sku;
					WholePileConfig wpcObj = wpcMap.get(key);
					//如果没有配置则不按照整托批次生成
					if(wpcObj==null){
						continue;
					}
					if(skuOrderMap.containsKey(key) ){
						skuOrderMap.get(key).add(orderno);
					}else {
						List<String> ordersList = new ArrayList<String>();
						ordersList.add(orderno);
						skuOrderMap.put(key, ordersList);
					}
				}
				
				
				int count = 0;
				Set<String> keySet = skuOrderMap.keySet();
				Iterator<String> iterator = keySet.iterator();
				
				while(iterator.hasNext()) {
					String key = iterator.next();
//					String[] keys = key.split(":");
//					String cusCode = keys[1];
//					String sku=keys[2];
					//获取整托配置
					WholePileConfig wpcObj = wpcMap.get(key);
					//如果没有配置则不按照整托批次生成
					if(wpcObj==null){
						continue;
					}
					List<String> ordersList = skuOrderMap.get(key);
					int ys = ordersList.size()/wpcObj.getWholePileQty();
					ordersList = ordersList.subList(0, wpcObj.getWholePileQty()*ys);
					//只生成一个批次
					if(ordersList.size()>0&&count==0){
						count=1;
						now=new Date();
						workBatch=new WorkBatch();
						workBatch.setBatchType(curUser.getUserType());    // 批次类型 （ customer:商家批次 paiu:派友批次）
						workBatch.setCreateTime(now);
						workBatch.setCustomerCode(customerCode);
						workBatch.setCompanyCode(companyCode);
						workBatch.setWarehouseCode(warehouseCode);
						workBatch.setCreaterId(user.id);
						workBatch.setPickType(pickType); 
						workBatch.setStatus("1"); //批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
						workBatch.setBillType(billType);
						workBatch.setFlowType(flowType);
						workBatch.setTacticsType(tacticsType);
						
						workBatch.setPrioritySendFlag(psFlag);//优先派送标志
						
						batchList.add(workBatch);
						this.workBatchDao.save(workBatch);
						
						Long id=workBatch.getId();
						String batchCode="B"+workBatch.getCustomerCode()+df.format(id);
						workBatch.setBatchCode(batchCode);
					}
					for(int z = 0 ; z < ordersList.size();z++){
						String orderno = ordersList.get(z);
						
						//关联批次和订单数据
						WorkOrder workOrder = new WorkOrder();
						workOrder.setCreateTime(now);
						workOrder.setBatchCode(workBatch.getBatchCode());
						workBatch.setOrderQty(workBatch.getOrderQty()==null?1:workBatch.getOrderQty()+1);
						
						WorkOrder workOrder_check=this.workOrderDao.loadOrderByOrderno(orderno);
						if(workOrder_check!=null){
							throw new Exception("重复创建批次，订单号："+orderno);
						}
						
						EdiOrder order=this.ediOrderDao.findByOrdeno(orderno);
						workOrder.setNeedInvoice(TransferHelper.boolean2String(order.getIsInvoice()));//是否需要发票
						workOrder.setCustomerOrderno(order.getCustomerOrdeno());
						workOrder.setFromno(order.getFromno());
						workOrder.setCustomerCode(workBatch.getCustomerCode());
						workOrder.setWarehouseCode(workBatch.getWarehouseCode());
						workOrder.setOrder(order);
						workOrder.setStatus("1"); //订单状态 (1.创建批次 2.创建任务 3.已拣货  4.已灯光拣选  9.待包装  5.已包装  6.已发货  7.已签收  8.异常 )
						workOrder.setBillType(billType);
						workOrder.setFlowType(flowType);
						workOrder.setEbillStatus("uncreate");
						workOrder.setCancelStatus("ok");
						workOrder.setPkgLock("unpkg");
						
						workOrder.setPrioritySendFlag(psFlag);//优先派送标志
						
						String goodsInfo=this.getGoodsInfo(orderno);
						workOrder.setGoodsInfo(goodsInfo);
						
						List<EdiOrderItem> orderItems=this.ediOrderItemDao.findByOrdeno(orderno);
						for (EdiOrderItem orderItem : orderItems) {
							workOrder.setGoodsNum(workOrder.getGoodsNum()+orderItem.getQty());
						}
						
						workOrderList.add(workOrder);
						
//						SynchroShippedBatchQueue.putSendMessageQueue("warehouseInfo"+StatusEnums.split.getStatus()
//								+orderno + "_jiedan");
						//订单日志
						OrderLog orderlog=new OrderLog(workOrder.getOrder().getOrdeno(),
								customerCode, 
								"1", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据）
								curUser,
								new Date(),
								null, 
								curUser.getRealname()+"创建作业批次");
						orderLogList.add(orderlog);
						
						//修改订单状态
						EdiOrder ediOrder=this.ediOrderDao.findByOrdeno(orderno);
						ediOrder.setStatus("finish"); //订单状态   (finish:生成批次   pending:准备状态)
						ediOrder.setMessage("sf");
						ediOrder.setBatchTaskCode(workBatch.getBatchCode());
						orderList.add(ediOrder);
					}
				}
			}else {
				for (int i = 0; i < ordersArray.length; i++) {
				    
				    String orderno = ordersArray[i];
                    List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(orderno);
                    String sku=itemList.get(0).getSku();
                    
					if("onesku".equals(tacticsType) && "single".equals(pickType)){
						if(!sku_last.equals(sku)){ 
							sku_last=sku;
							now=new Date();
							//创建新的批次
							workBatch=new WorkBatch();
							workBatch.setBatchType(curUser.getUserType());    // 批次类型 （ customer:商家批次 paiu:派友批次）
							workBatch.setCreateTime(now);
							workBatch.setCustomerCode(customerCode);
							workBatch.setCompanyCode(companyCode);
							workBatch.setWarehouseCode(warehouseCode);
							workBatch.setCreaterId(user.id);
							workBatch.setPickType(pickType); 
							workBatch.setStatus("1"); //批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
							workBatch.setBillType(billType);
							workBatch.setFlowType(flowType);
							workBatch.setTacticsType(tacticsType);
							
							workBatch.setPrioritySendFlag(psFlag);//优先派送标志
							
							batchList.add(workBatch);
							this.workBatchDao.save(workBatch);
							
						   //设置batchCode
						   Long id=workBatch.getId();
						   String batchCode="B"+workBatch.getCustomerCode()+df.format(id);
						   workBatch.setBatchCode(batchCode);
							
							//工作日志
							workLog=new WorkLog(workBatch.getBatchCode(),"1", user.getRealname()+"创建作业批次("+batchCode+")", now, curUser);
							workLogList.add(workLog);
							
						}
						
					}else if("promotion".equals(tacticsType)){
						if(!sku_last.equals(sku)){ 
							sku_last=sku;
							now=new Date();
							//创建新的批次
							workBatch=new WorkBatch();
							workBatch.setBatchType(curUser.getUserType());    // 批次类型 （ customer:商家批次 paiu:派友批次）
							workBatch.setCreateTime(now);
							workBatch.setCustomerCode(customerCode);
							workBatch.setCompanyCode(companyCode);
							workBatch.setWarehouseCode(warehouseCode);
							workBatch.setCreaterId(user.id);
							workBatch.setPickType(pickType); 
							workBatch.setStatus("1"); //批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
							workBatch.setBillType(billType);
							workBatch.setFlowType(flowType);
							workBatch.setTacticsType(tacticsType);
							
							workBatch.setPrioritySendFlag(psFlag);//优先派送标志
							
							batchList.add(workBatch);
							this.workBatchDao.save(workBatch);
							
						   //设置batchCode
						   Long id=workBatch.getId();
						   String batchCode="B"+workBatch.getCustomerCode()+df.format(id);
						   workBatch.setBatchCode(batchCode);
							
							//工作日志
							workLog=new WorkLog(workBatch.getBatchCode(),"1", user.getRealname()+"创建作业批次("+batchCode+")", now, curUser);
							workLogList.add(workLog);
							
						}
					}else{
						if(i%orderNum==0){ 
							now=new Date();
							//创建新的批次
							workBatch=new WorkBatch();
							workBatch.setBatchType(curUser.getUserType());    // 批次类型 （ customer:商家批次 paiu:派友批次）
							workBatch.setCreateTime(now);
							workBatch.setCustomerCode(customerCode);
							workBatch.setCompanyCode(companyCode);
							workBatch.setWarehouseCode(warehouseCode);
							workBatch.setCreaterId(user.id);
							workBatch.setPickType(pickType); 
							workBatch.setStatus("1"); //批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
							workBatch.setBillType(billType);
							workBatch.setFlowType(flowType);
							workBatch.setTacticsType(tacticsType);
							
							workBatch.setPrioritySendFlag(psFlag);//优先派送标志
							
							batchList.add(workBatch);
							this.workBatchDao.save(workBatch);
							
						   //设置batchCode
						   Long id=workBatch.getId();
						   String batchCode="B"+workBatch.getCustomerCode()+df.format(id);
						   workBatch.setBatchCode(batchCode);
							
							//工作日志
							workLog=new WorkLog(workBatch.getBatchCode(),"1", user.getRealname()+"创建作业批次("+batchCode+")", now, curUser);
							workLogList.add(workLog);
							log.info( user.getRealname()+"创建作业批次("+batchCode+")");
						}
						
					}
					//关联批次和订单数据
					WorkOrder workOrder = new WorkOrder();
					workOrder.setCreateTime(now);
					workOrder.setBatchCode(workBatch.getBatchCode());
					workBatch.setOrderQty(workBatch.getOrderQty()==null?1:workBatch.getOrderQty()+1);
					
					WorkOrder workOrder_check=this.workOrderDao.loadOrderByOrderno(orderno);
					if(workOrder_check!=null){
						throw new Exception("重复创建批次，订单号："+orderno);
					}
					EdiOrder order=this.ediOrderDao.findByOrdeno(orderno);
					workOrder.setNeedInvoice(TransferHelper.boolean2String(order.getIsInvoice()));//是否需要发票
					workOrder.setCustomerOrderno(order.getCustomerOrdeno());
					workOrder.setFromno(order.getFromno());
					workOrder.setCustomerCode(workBatch.getCustomerCode());
					workOrder.setWarehouseCode(workBatch.getWarehouseCode());
					workOrder.setOrder(order);
					workOrder.setStatus("1"); //订单状态 (1.创建批次 2.创建任务 3.已拣货  4.已灯光拣选  9.待包装  5.已包装  6.已发货  7.已签收  8.异常 )
					workOrder.setBillType(billType);
					workOrder.setFlowType(flowType);
					workOrder.setEbillStatus("uncreate");
					workOrder.setCancelStatus("ok");
					workOrder.setPkgLock("unpkg");
					workOrder.setPrioritySendFlag(psFlag);//优先派送标志
					workOrder.setGoodsInfo(this.getGoodsInfo(orderno));
					for (EdiOrderItem orderItem : itemList) {
						workOrder.setGoodsNum(workOrder.getGoodsNum()+orderItem.getQty());
					}
					workOrderList.add(workOrder);
					
					//订单日志
					OrderLog orderlog=new OrderLog(workOrder.getOrder().getOrdeno(),
							customerCode, 
							"1", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据）
							curUser,
							new Date(),
							null, 
							curUser.getRealname()+"创建作业批次");
					orderLogList.add(orderlog);
					
					//修改订单状态
					order.setStatus("finish"); //订单状态   (finish:生成批次   pending:准备状态)
					order.setMessage("sf");
					order.setBatchTaskCode(workBatch.getBatchCode());
					orderList.add(order);
			  }
		   }
            this.workBatchDao.save(batchList);
            this.ediOrderDao.save(orderList);
            this.workLogDao.save(workLogList);
            this.orderLogDao.save(orderLogList);
            this.workOrderDao.save(workOrderList);
            //update LiBin 发送奇门改为异步传输
            for (EdiOrder ediOrder : orderList) {
                InterfaceTask interfaceTask = new InterfaceTask();
                interfaceTask.setType(InterfaceTaskEnum.TYPE_QM_DELIVERY_CREATEBATCH);
                interfaceTask.setRelatedNo(ediOrder.getOrdeno());
                interfaceTask.setRelatedId(ediOrder.getId());
                interfaceTask.setCreatedTime(new Date());
                interfaceTaskService.saveTask(interfaceTask);
            }
          
		} catch (IOException e) {
			log.error("-----发送奇门出库单流水信息发送完毕 仓库接单 error",e);
		}

	}
	/**
	 * 
	 * @param workBatch
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void updateBatch(WorkBatch workBatch)
	{
		this.workBatchDao.updateSyncStatus(workBatch.getBatchCode(), workBatch.getSyncStatus());
	}

	/**
	 * 获取商品需求字符串
	 * @param orderno 订单号
	 * @return
	 */
	public String getGoodsInfo(String orderno) {
        StringBuilder sb=new StringBuilder();
        
        //获取map
        List<EdiOrderItem> orderItemList=this.ediOrderItemDao.findByOrdeno(orderno);
		Map<String, Integer> orderItemMap=new HashMap<String, Integer>();
		for (EdiOrderItem orderItem : orderItemList) {
			String sku=orderItem.getSku();
			int num=orderItem.getQty();
			if(orderItemMap.containsKey(sku)){
				orderItemMap.put(sku, orderItemMap.get(sku)+num);
			}else{
				orderItemMap.put(sku, num);
			}
		}
		
		//排序
		List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(orderItemMap.entrySet());
		Collections.sort(mappingList,
				new Comparator<Map.Entry<String, Integer>>() {
					public int compare(
							Map.Entry<String, Integer> mapping1,
							Map.Entry<String, Integer> mapping2) {
						return mapping1.getKey().compareTo(mapping2.getKey());
					}
		});
		
		//生成字符串
		for (Map.Entry<String, Integer> mapping : mappingList) {
			String key = mapping.getKey();
			
			if(sb.length()>0){
				sb.append(";");
			}
			sb.append(key).append(":").append(mapping.getValue());
		}
		
		return sb.toString();
	}

	/**
	 * 查找作业批次
	 * @param param 查询参数
	 * @return
	 */
	public List<WorkBatch> loadWorkBatch(Map<String, Object> param) {
		Specification<WorkBatch> spec = getWhereClause(param);
		Sort sort = new Sort(Direction.DESC, "id");
		List<WorkBatch> workBatchList = this.workBatchDao.findAll(spec,sort);
		Map<String,Object> cacheMap = new HashMap<String,Object>();
		for (WorkBatch workBatch : workBatchList) {
			//换成使用缓存
			this.setDetail(workBatch,cacheMap);
//			this.setDetail(workBatch);
		}
		return workBatchList;
	}
	
	/**
	 * 分页查询方式，组合特定的查询条件
	 * 
	 * @param 
	 * @return 
	 * @author <a href=mailto:libin@nryuncang.com>libin</a>
	 * @version 0.0.16
	 */
	public Page<WorkBatch> loadPageWorkBatch(Map<String, Object> param, int pageNumber, int pageSize) {
	    
	    Sort sort = new Sort(Direction.DESC, "id");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize,sort);
        Specification<WorkBatch> spec = getWhereClause(param);
        Page<WorkBatch> page = workBatchDao.findAll(spec, pageRequest);
        
        Map<String,Object> cacheMap = new HashMap<String,Object>();
        for (WorkBatch workBatch : page) {
            this.setDetail(workBatch,cacheMap);
        }
        
        return page;
    }
	
	/**
	 * 分页
	 * @param paramHolder
	 * @return
	 */
	public Page<WorkBatch> PageWorkBatch(QueryParamHolder paramHolder) {
		Page<WorkBatch> workBatchs = findByJson(paramHolder, workBatchDao, WorkBatch.class);
		return workBatchs;
	}
	
	/**
	 * 查询条件封装
	 * @param searchParams
	 * @return
	 */
	private Specification<WorkBatch> getWhereClause(final Map<String, Object> searchParams) {
		
		return new Specification<WorkBatch>(){
			
		    @Override
		    public Predicate toPredicate(Root<WorkBatch> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		      
		      //customerCodes
		      String customerCodes=(String) searchParams.get("customerCodes");
		      if(StringUtils.isBlank(customerCodes)){
		    	  customerCodes="blank";
		      }
			  String[] customerCodeSplit = customerCodes.split(":");
			  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
			  int i = 0;
			  for (String _customerCode : customerCodeSplit) {
				 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), _customerCode);
				 i++;
			  }
			  pre.getExpressions().add(cb.or(tempCustomerCode));
		      
		      //areagroups
		      String areagroups=(String) searchParams.get("areagroups");
		      if(StringUtils.isBlank(areagroups)){
		    	  areagroups="blank";
		      }
			  String[] areagroupSplit = areagroups.split(":");
			  ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
			  int j = 0;
			  for (String _areagroup : areagroupSplit) {
					areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
					j++;
			  }
			  pre.getExpressions().add(cb.or(areagroupArray));
			  
              //createTime
		      Date fromDate= (Date) searchParams.get("fromDate");
		      if (fromDate != null) {
		        pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("createTime"), fromDate));
		      }
		      
		      Date toDate= (Date) searchParams.get("toDate");
		      if (toDate != null) {
		        pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("createTime"), toDate));
		      }
		      
		      //status
		      String status=(String) searchParams.get("status");
		      if(StringUtils.isNotBlank(status)){
					pre.getExpressions().add(cb.equal(r.get("status"),status));
			  }	
		      
		      //pickType
		      String pickType=(String) searchParams.get("pickType");
		      if(StringUtils.isNotBlank(pickType)){
					pre.getExpressions().add(cb.equal(r.get("pickType"),pickType));
			  }	
		      
		      //batchCode
		      String batchCode=(String) searchParams.get("batchCode");
		      if(StringUtils.isNotBlank(batchCode)){
					pre.getExpressions().add(cb.equal(r.get("batchCode"),batchCode.trim()));
			  }	
		      String companyCode=(String) searchParams.get("companyCode");
		      if(StringUtils.isNotBlank(companyCode)){
					pre.getExpressions().add(cb.equal(r.get("companyCode"),companyCode.trim()));
			  }	
		      
				// 优先派送标志
				String psFlag = (String) searchParams.get("psFlag");
				if (StringUtils.isNotBlank(psFlag)) {
					if ("-1".equals(psFlag)) {
						ComparisonPredicate[] prioritySendFlagArray = new ComparisonPredicate[2];
						prioritySendFlagArray[0] = (ComparisonPredicate) cb.equal(r.get("prioritySendFlag"), "0");
						prioritySendFlagArray[1] = (ComparisonPredicate) cb.equal(r.get("prioritySendFlag"), "1");
						pre.getExpressions().add(cb.or(prioritySendFlagArray));
					} else {
						pre.getExpressions().add(cb.equal(r.get("prioritySendFlag"), psFlag));
					}
				}

		      return pre;
		    }
		  };
    }
	
	/**
	 * 根据批次编号查找批次
	 * @param workBatchCode 批次编号
	 * @return
	 */
	public WorkBatch loadWorkBatchByCode(String workBatchCode) {
		WorkBatch batch= this.workBatchDao.loadbatchByBatchCode(workBatchCode);
		this.setDetail(batch);
		return batch;
	}
	
	/**
	 * 设置属性
	 * @param batch
	 */
	private void setDetail(WorkBatch batch){
		//customer
		String customerCode=batch.getCustomerCode();
		Customers customer=this.customersDao.findByCustomerCode(customerCode);
		batch.setCustomer(customer);
		
		//warehouse
		String warehouseCode=batch.getWarehouseCode();
		AreaGroup warehouse=this.areaGroupDao.findByGroupCode(warehouseCode);
		batch.setWarehouse(warehouse);
		
		//creater
		User user=this.userDao.findOne(batch.getCreaterId());
		batch.setCreater(user);
		
	}
	
	/**
	 * 设置属性使用缓存
	 * @param batch
	 */
	private void setDetail(WorkBatch batch,Map<String,Object> cacheMap){
		//customer
		String customerCode=batch.getCustomerCode();
		Customers customer=null;
		if(cacheMap.containsKey("customer_"+customerCode)){
			customer = (Customers)cacheMap.get("customer_"+customerCode);
		}else {
			customer = this.customersDao.findByCustomerCode(customerCode);
			cacheMap.put("customer_"+customerCode, customer);
		}
		batch.setCustomer(customer);
		
		//warehouse
		String warehouseCode=batch.getWarehouseCode();
		AreaGroup warehouse=null;
		if(cacheMap.containsKey("areaGroup_"+warehouseCode)){
			warehouse = (AreaGroup)cacheMap.get("areaGroup_"+warehouseCode);
		}else {
			warehouse=this.areaGroupDao.findByGroupCode(warehouseCode);
			cacheMap.put("areaGroup_"+warehouseCode, warehouse);
		}
		batch.setWarehouse(warehouse);
		
		//creater
		User user=null;
		if(cacheMap.containsKey("user_"+batch.getCreaterId())){
			user = (User)cacheMap.get("user_"+batch.getCreaterId());
		}else {
			user=this.userDao.findOne(batch.getCreaterId());
			cacheMap.put("user_"+batch.getCreaterId(), user);
		}
		batch.setCreater(user);
		
	}
	/**
	 * 绑定流转箱
	 * @param taskCode
	 * @param workBoxCode
	 * @return success:绑定成功  busy:流转箱被占用   error:流转箱条码异常
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String sendBatch(String batchcode) throws Exception {
		try {
			WorkBatch workBatch = this.loadWorkBatchByCode(batchcode);
			if(null == workBatch)
			{
				return null;
			}
			else
			{
				Batch batch = new Batch();
				batch.setBox_num(1);
				batch.setCustomer_code(workBatch.getCustomerCode());
				batch.setBatch(workBatch.getBatchCode());
				batch.setEndpoints(workBatch.getWarehouseCode());
				batch.setShipped_time(TimeUtil.getNowDateString(workBatch.getCreateTime()));
				batch.setStartpoints("0755");
				List<Box> boxList = new ArrayList<Box>();
				List<Order> orderList = new ArrayList<Order>();
				List<WorkTask> workTasks = this.workTaskDao.loadTaskByBatchCode(workBatch.getBatchCode());
				
				for(WorkTask wt : workTasks)
				{
					 Box box = new Box();
					 box.setBox_code(wt.getTaskCode());
					 box.setBox_type(workBatch.getPickType());
					 box.setGoods_num(Integer.parseInt(wt.getGoodsNum()+"")); 
					 box.setWeight(0);
				 
					 List<Box_detail> skuList = new ArrayList<Box_detail>();
					 List<WorkTaskItem> wtis = workTaskItemDao.loadByTaskCode(wt.getTaskCode());
					 for(WorkTaskItem wti : wtis) 
					 { 
						 Box_detail sku = new Box_detail(); 
						 sku.setBox(box.getBox_code()); 
						 sku.setNum(wti.getPickedNum());
						 sku.setSku(wti.getSku());
						 skuList.add(sku); 
					 } 
					 box.setBox_detail(skuList); 
					 boxList.add(box);
				}
				
				int sun_num = 0;
				List<WorkOrder> workOrders = this.workOrderDao.loadOrderByBatchCode(batchcode);
				for(WorkOrder wo : workOrders)
				{
					Order order = new Order();
					order.setOrdeno(wo.getOrder().getOrdeno());
					order.setFromno(wo.getOrder().getFromno());
					order.setOrder_type(workBatch.getPickType());
					order.setSku_num(wo.getGoodsNum());
					String expressNo="";
					if("cbill".equals(wo.getBillType()))
					{
						expressNo = wo.getExpressNo();
					}
					else
					{
						expressNo = wo.getEbillNo();
					}
					order.setExpressNo(expressNo);
					order.setExpressCode(wo.getExpressCompany());
					order.setExpressName(wo.getExpressName());
					
					Integer wi = wo.getWeight();
					if(null == wi)
					{
						wi = 0;
					}
					order.setWeight(wi);
					sun_num += wo.getGoodsNum();
					orderList.add(order);
				}
				batch.setGoods_num(sun_num);
				batch.setOrder_num(workBatch.getOrderQty());
				batch.setBox(boxList);
				batch.setOrder(orderList);
				ObjectMapper objectMapper = new ObjectMapper();
				return objectMapper.writeValueAsString(batch);
				/*try {
					String result = SystemUtil.pub(
							"http://tms.paiu.com.cn/tms/api/wms/batch", "appkey=123&appsecret=123&data=" + );
					JSONObject json2 = JSONObject.fromObject(result);
					String status= json2.getString("status");
					if("1".equals(status))
					{
						workBatch.setSyncStatus("finish");
						this.workBatchDao.updateSyncStatus(workBatch.getBatchCode(), workBatch.getSyncStatus());
					}
					return result;
				} catch (JsonGenerationException e) {
					// TODO Auto-generated catch block
					
				} catch (JsonMappingException e) {
					// TODO Auto-generated catch block
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					
				}
				return json.toString();*/
			}
		
		} catch (Exception e) {
			
			return null;
		}
	}
	
	/**
	 * 
	 * 标记为优先派送
	 *
	 * @param ordernos
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean signPriorSend(String orderno) throws Exception {
			// 标记为优先派送
			int count = ediOrderDao.updateEdiOrderPrioritySendFlag("1", orderno);
			return  count == 1 ?  true : false; 
			
	}
	
	
	
	/**
	 * 
	 * 
	 *确认分配快递
	 * @param selectedOrder
	 * @param psCompanyCode
	 * @return
	 * @throws Exception [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String assignCompany(String selectedOrder,String psCompanyCode) throws Exception {
		String[] ordernos = selectedOrder.split(",");
		EdiOrder ediOrder = null;
		for(String orderno :ordernos){
			if(StringUtils.isEmpty(orderno)||StringUtils.isEmpty(psCompanyCode)){
				continue;
			}
			ediOrder = ediOrderDao.findByOrdeno(orderno);
			if (!"TTKDEX".equals(psCompanyCode)) {
				ediOrder.setPrioritySendFlag("0");
			}
			ediOrder.setCacode(psCompanyCode);
			ediOrderDao.save(ediOrder);
		}
		return "success";
	}
	
	
}